/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.ext.bpm;

import org.zkoss.lang.Objects;
import org.zkoss.zk.au.AuRequest;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.sys.ContentRenderer;
import org.zkoss.zul.impl.XulElement;

import cn.easyplatform.web.ext.Assignable;
import cn.easyplatform.web.ext.ManagedExt;
import cn.easyplatform.web.ext.Widget;
import cn.easyplatform.web.ext.ZkExt;
import cn.easyplatform.web.ext.bpm.event.NodeEvent;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class Bpmdesigner extends XulElement implements ZkExt, ManagedExt,
		Assignable {

	public final static String ON_SAVE = "onSave";

	static {
		addClientEvent(Bpmdesigner.class, NodeEvent.ON_NODE,
				CE_DUPLICATE_IGNORE | CE_REPEAT_IGNORE);
		addClientEvent(Bpmdesigner.class, ON_SAVE, CE_IMPORTANT
				| CE_REPEAT_IGNORE | CE_NON_DEFERRABLE);
		addClientEvent(Bpmdesigner.class, Events.ON_OPEN, CE_DUPLICATE_IGNORE
				| CE_REPEAT_IGNORE);
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 流程id
	 */
	private String _processId = "";

	/**
	 * 实例id
	 */
	private String _orderId = "";

	/**
	 * 模型
	 */
	private String _model = "";

	/**
	 * 活动功能
	 */
	private String _task = "";

	/**
	 * 是否可修改
	 */
	private boolean _editable;

	/**
	 * 设计时选择功能触发的事件
	 */
	private String _taskEvent;

	/**
	 * 设计时选择参与人触发的事件
	 */
	private String _assigneeEvent;

	/**
	 * 设计时选择参机构触发的事件
	 */
	private String _assigneeTypeEvent;

	/**
	 * 设计时选择参与角色触发的事件
	 */
	private String _assigneeRoleEvent;
	
	
	/**
	 * 设计时选择分支触发的事件
	 */
	private String _decisionEvent;

	/**
	 * 流程内容
	 */
	private String _value;

	/**
	 * @return the assigneeTypeEvent
	 */
	public String getAssigneeTypeEvent() {
		return _assigneeTypeEvent;
	}

	/**
	 * @param assigneeTypeEvent the assigneeTypeEvent to set
	 */
	public void setAssigneeTypeEvent(String assigneeTypeEvent) {
		this._assigneeTypeEvent = assigneeTypeEvent;
	}

	/**
	 * @return the assigneeRoleEvent
	 */
	public String getAssigneeRoleEvent() {
		return _assigneeRoleEvent;
	}

	/**
	 * @param assigneeRoleEvent the assigneeRoleEvent to set
	 */
	public void setAssigneeRoleEvent(String assigneeRoleEvent) {
		this._assigneeRoleEvent = assigneeRoleEvent;
	}

	/**
	 * @return the taskEvent
	 */
	public String getTaskEvent() {
		return _taskEvent;
	}

	/**
	 * @param taskEvent
	 *            the taskEvent to set
	 */
	public void setTaskEvent(String taskEvent) {
		this._taskEvent = taskEvent;
	}

	/**
	 * @return the assigneeEvent
	 */
	public String getAssigneeEvent() {
		return _assigneeEvent;
	}

	/**
	 * @param assigneeEvent
	 *            the assigneeEvent to set
	 */
	public void setAssigneeEvent(String assigneeEvent) {
		this._assigneeEvent = assigneeEvent;
	}

	/**
	 * @return the decisionEvent
	 */
	public String getDecisionEvent() {
		return _decisionEvent;
	}

	/**
	 * @param decisionEvent
	 *            the decisionEvent to set
	 */
	public void setDecisionEvent(String decisionEvent) {
		this._decisionEvent = decisionEvent;
	}

	/**
	 * @return the editable
	 */
	public boolean isEditable() {
		return _editable;
	}

	/**
	 * @param editable
	 *            the editable to set
	 */
	public void setEditable(boolean editable) {
		if (this._editable != editable) {
			this._editable = editable;
			smartUpdate("editable", editable);
		}
	}

	public String getProcessId() {
		return _processId;
	}

	public void setProcessId(String processId) {
		this._processId = processId;
	}

	public String getOrderId() {
		return _orderId;
	}

	public void setOrderId(String orderId) {
		if (!_orderId.equals(orderId)) {
			this._orderId = orderId;
			smartUpdate("orderId", _orderId);
		}
	}

	public void setModel(String model) {
		if (!_model.equals(model)) {
			this._model = (String) model;
			smartUpdate("model", _model);
		}
	}

	@Override
	public void setValue(Object value) {
		if (!Objects.equals(value, this._value)) {
			this._value = (String) value;
			Widget ext = (Widget) getAttribute("$proxy");
			ext.reload(this);
		}
	}

	@Override
	public Object getValue() {
		return _value;
	}

	public String getTask() {
		return _task;
	}

	public void setTask(String task) {
		if (!_task.equals(task)) {
			this._task = task;
			smartUpdate("task", _task);
		}
	}

	public void setInputValue(Object value) {
		smartUpdate("inputValue", value);
	}

	public void setNodeState(String json) {
		smartUpdate("nodeState", json);
	}

	protected void renderProperties(ContentRenderer renderer)
			throws java.io.IOException {
		super.renderProperties(renderer);
		render(renderer, "model", _model);
		render(renderer, "task", _task);
		render(renderer, "order", _orderId);
		render(renderer, "editable", _editable);
	}

	public void service(AuRequest req, boolean everError) {
		final String cmd = req.getCommand();
		if (cmd.equals(NodeEvent.ON_NODE))
			Events.postEvent(NodeEvent.getNodeEvent(req));
		else if (cmd.equals(ON_SAVE)) {
			this._value = convertXml((String) req.getData().get("data"));
			if (!(Boolean) req.getData().get("ign"))
				Events.postEvent(new Event(ON_SAVE, this, this._value));
		} else if (cmd.equals(Events.ON_OPEN)) {
			Events.postEvent(new Event(Events.ON_OPEN, this, req.getData()));
		} else
			super.service(req, everError);
	}

	private String convertXml(String value) {
		if (value.indexOf("#1") != -1) {
			value = value.replaceAll("#1", "'");
		}
		if (value.indexOf("#2") != -1) {
			value = value.replaceAll("#2", "\"");
		}
		if (value.indexOf("#5") != -1) {
			value = value.replaceAll("#5", "&gt;");
		}
		if (value.indexOf("#6") != -1) {
			value = value.replaceAll("#6", "&lt;");
		}
		if (value.indexOf("&") != -1) {
			value = value.replaceAll("#7", "&amp;");
		}
		return value;
	}
}
